package com.citywithincity.utils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.citywithincity.api.IFileReader;
import com.citywithincity.api.utils.ApiUtil;

/**
 * 从map中取出数据
 * 
 * @author Randy
 *
 */
public class MapUtil {

	public static int MAX_LEN = 300;

	public static int getInt(Map<String, ?> map, String key) {
		return (Integer) map.get(key);
	}

	public static double getDouble(Map<String, ?> map, String key) {
		return (Double) map.get(key);
	}

	public static boolean getBoolean(Map<String, ?> map, String key) {
		return (Boolean) map.get(key);
	}

	public static float getFloat(Map<String, ?> map, String key) {
		return (Float) map.get(key);
	}

	public static long getLong(Map<String, ?> map, String key) {
		return (Long) map.get(key);
	}

	public static String toString(Map<String, ?> json) {
		StringBuilder stringBuilder = new StringBuilder("{");
		toString(stringBuilder,json);
		return stringBuilder.toString();
	}
	
	public static void toString(StringBuilder stringBuilder,Map<String, ?> json){
		boolean first = true;
		for (Entry<String, ?> entry : json.entrySet()) {
			if (first) {
				first = false;
			} else {
				stringBuilder.append(',');
			}
			stringBuilder.append(entry.getKey());
			stringBuilder.append(':');
			String value = String.valueOf(entry.getValue());
			stringBuilder.append(value);
		}
		stringBuilder.append('}');
		
	}

	public static String toQueryString(Map<String, ?> json) {
		StringBuilder stringBuilder = new StringBuilder();
		boolean first = true;
		for (Entry<String, ?> entry : json.entrySet()) {
			if (first) {
				first = false;
			} else {
				stringBuilder.append('&');
			}
			stringBuilder.append(entry.getKey());
			stringBuilder.append('=');
			String value = String.valueOf(entry.getValue());
			stringBuilder.append(value);
		}
		return stringBuilder.toString();

	}

	public static IFileReader getReader(Map<String, Object> json) {
		IFileReader reader = (IFileReader) json.get(ApiUtil.fileReader);
		json.remove(ApiUtil.fileReader);
		return reader;
	}

	/**
	 * 
	 * @param oldData
	 * @param newData
	 *            多的，或者修改的
	 * @return
	 */
	public static Map<String, Object> compare(Map<String, Object> oldData, Map<String, Object> newData) {
		Map<String, Object> tm = new HashMap<String, Object>();
		tm.putAll(newData);
		for (Entry<String, Object> oldEntry : oldData.entrySet()) {
			Object oldVale = oldEntry.getValue();
			String key = oldEntry.getKey();
			Object newValue = tm.get(key);
			if (oldVale == null && oldVale == newValue) {
				tm.remove(key);
			}
		}

		return null;
	}

	@SuppressWarnings("unchecked")
	public static <T> T mapToObject(Map<String, Object> map, Class<T> type) {
		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(type); // 获取类属性
			Object obj = type.newInstance(); // 创建 JavaBean 对象

			// 给 JavaBean 对象的属性赋值
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (int i = 0; i < propertyDescriptors.length; i++) {
				PropertyDescriptor descriptor = propertyDescriptors[i];
				String propertyName = descriptor.getName();

				if (map.containsKey(propertyName)) {
					// 下面一句可以 try 起来，这样当一个属性赋值失败的时候就不会影响其他属性赋值。
					Object value = map.get(propertyName);
					descriptor.getWriteMethod().invoke(obj, value);
				}
			}
			return (T) obj;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static Map<String, Object> objectToMap(Object bean,Map<String, Object> target) {
		try {
			Class type = bean.getClass();
			BeanInfo beanInfo = Introspector.getBeanInfo(type);

			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (int i = 0; i < propertyDescriptors.length; i++) {
				PropertyDescriptor descriptor = propertyDescriptors[i];
				String propertyName = descriptor.getName();
				if (!propertyName.equals("class")) {
					Method readMethod = descriptor.getReadMethod();
					Object result = readMethod.invoke(bean, new Object[0]);
					target.put(propertyName, result);
				}
			}
			return target;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}

	public static Map<String, Object> objectToMap(Object bean) {
		return objectToMap(bean, new HashMap<String, Object>());
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static List listToList(List<Map<String, Object>> src, Class<?> clazz) {
		try {
			List list = new ArrayList(src.size());
			for (Map<String, Object> map : src) {
				Object data = clazz.newInstance();
				mapToObject(map, data, clazz);
				list.add(data);
			}
			return list;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}

	private static void mapToObject(Map<String, Object> map, Object data, Class<?> type) {
		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(type); // 获取类属性
			// 给 JavaBean 对象的属性赋值
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (int i = 0; i < propertyDescriptors.length; i++) {
				PropertyDescriptor descriptor = propertyDescriptors[i];
				String propertyName = descriptor.getName();
				if (map.containsKey(propertyName)) {
					// 下面一句可以 try 起来，这样当一个属性赋值失败的时候就不会影响其他属性赋值。
					Object value = map.get(propertyName);
					descriptor.getWriteMethod().invoke(data, value);
				}
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}
